use crate::prelude::*;
use dashmap::{DashMap};

pub struct KvTable {
    inner: DashMap<Key, Value>,
    //hit: u32
}

impl KvTable {
    pub fn new() -> Self {
        KvTable { 
            inner: DashMap::default(),
            //hit: 0
        }
    }
    fn mainpulate_table_enter(&self)
    {
        //self.hit += 1;
    }
}

impl StorageService for KvTable {

    fn insert(&self, k: Key, v: Value) -> Result<() ,KvErr>
    {
        self.mainpulate_table_enter();
        match self.inner.contains_key(&k) {
            true => Err(KvErr::DUPLICATE),
            false => {self.inner.insert(k, v); Ok(())}
        }
    }
    fn lookup(&self, k: Key) -> Result<Value, KvErr>
    {
        self.mainpulate_table_enter();
        match self.inner.get(&k){
            Some(v) => Ok(v.clone()),
            None => Err(KvErr::NOTFOUND)
        }
    }
    fn delete(&self, k: Key) -> Result<(), KvErr>
    {
        self.mainpulate_table_enter();
        match self.inner.remove(&k) {
            Some(_) => Ok(()),
            None => Err(KvErr::NOTFOUND)
        }
    }
}

#[cfg(test)]
mod test {
    use crate::prelude::*;
    #[test]
    fn test_service()
    {
        let t = KvTable::new();
        let k = Key::STRING(String::from("hello"));
        let k2 = Key::STRING(String::from("hello2"));
        let v = Value::STRING(String::from("world"));

        t.insert(k.clone(), v.clone()).unwrap();
        assert_eq!(t.insert(k.clone(), v.clone()).unwrap_err(), KvErr::DUPLICATE);
        assert_eq!(t.lookup(k.clone()).unwrap(), v);
        assert_eq!(t.delete(k2.clone()).unwrap_err(), KvErr::NOTFOUND);
        t.delete(k.clone()).unwrap();
        assert_eq!(t.lookup(k.clone()).unwrap_err(), KvErr::NOTFOUND);
    }
}